package com.itcoon.cloud.framework.security.filter;

import com.itcoon.cloud.framework.security.config.properties.JwtTokenProperties;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.util.Base64Utils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 通过解析swagger 的basic auth的认证参数，获取用户数据，并生成jwtToken
 * @author Administrator
 * created in 2021/4/26
 */
public class SwaggerBasicAuthFilter extends OncePerRequestFilter {
	private static final String AUTH_VALUE_PREFIX = "Basic ";
	private AuthenticationProvider authenticationProvider;
	private AuthenticationEntryPoint authenticationEntryPoint;
	private JwtTokenProperties jwtTokenProperties;
	public SwaggerBasicAuthFilter(AuthenticationProvider authenticationProvider, AuthenticationEntryPoint authenticationEntryPoint, JwtTokenProperties jwtTokenProperties) {
		this.authenticationProvider = authenticationProvider;
		this.authenticationEntryPoint = authenticationEntryPoint;
		this.jwtTokenProperties = jwtTokenProperties;
	}

	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		String accessToken = request.getHeader(jwtTokenProperties.getHeaderName());
		if (accessToken != null && accessToken.startsWith(AUTH_VALUE_PREFIX)) {
			accessToken = accessToken.substring(AUTH_VALUE_PREFIX.length());
			String decodeStr = new String(Base64Utils.decodeFromString(accessToken));
			String[] datas = decodeStr.split(":");
			String account = datas[0];
			String password = datas[1];
			try {
				Authentication authentication = this.authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(account, password));
				onAuthenticationSuccess(request, response, authentication);
			} catch (AuthenticationException ex) {
				authenticationEntryPoint.commence(request, response, ex);
				return;
			}
		}
		filterChain.doFilter(request, response);
	}

	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
		SecurityContextHolder.getContext().setAuthentication(authentication);
	}
}
